package com.lxw.report.meta.query;
import com.lxw.report.engine.dataModel.report.ReportColumn;
import com.lxw.report.engine.dataModel.report.ReportDataRow;
import com.lxw.report.engine.dataModel.report.ReportDataSet;
import com.lxw.report.engine.dataModel.report.ReportParameter;
import com.lxw.report.engine.enums.BIColumnTypeEnum;
import com.lxw.report.meta.entity.DataBase;
import com.lxw.report.meta.query.queryer.Queryer;
import com.lxw.report.meta.query.queryer.QueryerFactory;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * 数据执行器类，负责选择正确的报表查询器并获取数据，最终转化为成报表的数据集
 *
 * @author lxw
 */
public class ReportDataSetExecutor {
    private ReportParameter parameter;
    private DataBase dataBase;
    private Queryer queryer;
    /**
     * 数据执行器
     */
    public ReportDataSetExecutor(DataBase dataBase, ReportParameter parameter) {
        this.dataBase = dataBase;
        this.parameter = parameter;
    }
    /**
     * 选择正确的报表查询器并获取数据，最终转化为成报表的数据集
     */
    public ReportDataSet execute(ReportGetRequest reportGetRequest) {
        ReportDataSet reportDataSet=null;
        final Queryer queryer = this.getQueryer();
        if (queryer == null) {
            throw new RuntimeException("未指定报表查询器对象!");
        }
        final List<ReportColumn> reportColumnList = this.parameter.getDataReportColumns();
        //布局列集合
        List<ReportColumn> layOutReportColumnList=new ArrayList<>();
        //如果有维度列,则使用内存分页,如果没有维度列则使用SQL分页
        for(ReportColumn reportColumn:reportColumnList){
            if (reportColumn.getBiColumnType() == BIColumnTypeEnum.LEFT_DIMENSION){
                layOutReportColumnList.add(reportColumn);
            }
        }

        Long count=0L;
        //查询得到每一行的数据, 如果有维度列 则查所有数据 在内存中进行分页, 否则通过limit进行分页
        List<ReportDataRow> reportDataRowList = queryer.getReportDataRowsBySqlAndColumns(this.parameter.getSqlText(),this.parameter.getDataReportColumns());
        //定义最终得到的行集合
        List<ReportDataRow> actualDataRows = new ArrayList<>();
        Boolean isPaging=reportGetRequest.getPagination()==null?false:reportGetRequest.getPagination();
        int pageSize=reportGetRequest.getPageSize();
        int beginItemIndex=reportGetRequest.getBeginItemIndex();
        //所有的的布局列key值集合
        Set<String> layOutKeySet=new LinkedHashSet<>();
        //对应的当前分页的布局列key值集合
        Set<String> layOutKeyPageSet=new LinkedHashSet<>();
        //获取所有的布局列key值
        for(ReportDataRow reportDataRow:reportDataRowList){
            String layOutKey=reportDataRow.getLayOutRowKey();
            layOutKeySet.add(layOutKey);
        }
        //获取对应的分页的布局列key值集合
        int currentIndex=0;
        for(String layOutKey:layOutKeySet){
            currentIndex++;
            if(pageSize!=0&&isPaging){
                if(currentIndex>beginItemIndex&&currentIndex<=(beginItemIndex+pageSize)){
                    layOutKeyPageSet.add(layOutKey);
                }
            }else{
                layOutKeyPageSet.add(layOutKey);
            }
        }
        //根据分页后的布局列key值集合取数据
        for(ReportDataRow reportDataRow:reportDataRowList){
           if(layOutKeyPageSet.contains(reportDataRow.getLayOutRowKey())){
               actualDataRows.add(reportDataRow);
           }
        }
//        if(isPaging&&pageSize!=0){
//            if(hasDim){
//                count= Long.valueOf(layOutKeySet.size());
//            }else{
//                //如果数据的布局列有重复值,则该值不准;
//                count=queryer.getMetaDataRowsCount();
//            }
//        }
        reportDataSet = new ReportDataSet(actualDataRows, reportColumnList);
        reportDataSet.setTotalCount(count);
        reportDataSet.setPageNumber(reportGetRequest.getPageNumber());
        reportDataSet.setPageSize(reportGetRequest.getPageSize());
        return reportDataSet;
    }

    private Queryer getQueryer() {
        if (this.queryer != null) {
            return this.queryer;
        }
        return QueryerFactory.create(this.dataBase);
    }
}
